package com.yc.cloud.admin.controller;

import cn.hutool.core.codec.Base64;
import com.yc.cloud.admin.config.FaceRecognitionProperties;
import com.yc.cloud.admin.dto.request.FaceAddFileReqDTO;
import com.yc.cloud.admin.dto.request.FaceDetectReqDTO;
import com.yc.cloud.admin.dto.response.FaceAddFileRespDTO;
import com.yc.cloud.admin.dto.response.FaceDetectRespDTO;
import com.yc.cloud.admin.dto.response.FaceSearchRespDTO;
import com.yc.cloud.admin.service.FaceRecognitionService;
import com.yc.cloud.common.basic.api.ResponseResult;
import com.yc.cloud.common.basic.exception.Asserts;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

/**
 * 人脸识别控制器
 *
 * @author JackGu
 * @since 2025-11-05
 */
@Slf4j
@RestController
@RequestMapping("/face")
@Api(value = "人脸识别", tags = "人脸识别接口")
public class FaceRecognitionController {

    @Resource
    private FaceRecognitionService faceRecognitionService;

    @Resource
    private FaceRecognitionProperties faceRecognitionProperties;

    @PostMapping("/detect")
    @ApiOperation(value = "人脸检测", notes = "从上传的图片文件中检测人脸")
    public ResponseResult<FaceDetectRespDTO> detectFaceByFile(
            @ApiParam(value = "图片文件", required = true) @RequestParam("file") MultipartFile file) {
        
        if (file == null || file.isEmpty()) {
            Asserts.fail("图片文件不能为空");
        }

        try {
            // 将文件转换为Base64
            byte[] fileBytes = file.getBytes();
            String imageBase64 = Base64.encode(fileBytes);

            FaceDetectReqDTO reqDTO = new FaceDetectReqDTO();
            reqDTO.setImage(imageBase64);

            FaceDetectRespDTO result = faceRecognitionService.detectFace(reqDTO);
            return ResponseResult.success(result);

        } catch (IOException e) {
            log.error("读取文件异常", e);
            return ResponseResult.failed("读取文件失败: " + e.getMessage());
        }
    }

    @PostMapping("/add")
    @ApiOperation(value = "添加人脸", notes = "上传人脸图片并添加到人脸库")
    public ResponseResult<FaceAddFileRespDTO.FaceData> addFace(
            @ApiParam(value = "人脸图片文件", required = true) @RequestParam("file") MultipartFile file,
            @ApiParam(value = "人员ID（唯一标识）", required = true) @RequestParam("personId") String personId,
            @ApiParam(value = "人员姓名") @RequestParam(value = "personName", required = false) String personName,
            @ApiParam(value = "扩展信息（JSON格式）") @RequestParam(value = "metaInfo", required = false) String metaInfo) {

        FaceAddFileReqDTO reqDTO = FaceAddFileReqDTO.builder()
                .personId(personId)
                .personName(personName)
                .metaInfo(metaInfo)
                .build();
        
        FaceAddFileRespDTO result = faceRecognitionService.addFaceFile(file, reqDTO);
        if (result != null && result.isSuccess()) {
            return ResponseResult.success(result.getData());
        }
        return ResponseResult.failed(result != null ? result.getMsg() : "添加人脸失败");
    }

    @PostMapping("/delete/{faceId}")
    @ApiOperation(value = "删除人脸", notes = "从人脸库中删除指定ID的人脸")
    public ResponseResult<Boolean> deleteFace(
            @ApiParam(value = "人脸ID", required = true) @PathVariable String faceId) {

        Boolean result = faceRecognitionService.deleteFace(faceId);
        if (result) {
            return ResponseResult.success(result);
        }
        return ResponseResult.failed("删除人脸失败");
    }

    @GetMapping("/exists/{faceId}")
    @ApiOperation(value = "查询人脸是否存在", notes = "检查指定ID的人脸是否已存储")
    public ResponseResult<Boolean> existsFace(
            @ApiParam(value = "人脸ID", required = true) @PathVariable String faceId) {

        Boolean result = faceRecognitionService.existsFace(faceId);
        return ResponseResult.success(result);
    }

    @PostMapping("/search")
    @ApiOperation(value = "人脸搜索", notes = "上传图片在人脸库中搜索最匹配的人脸，返回topK个结果")
    public ResponseResult<FaceSearchRespDTO.SearchData> searchFaceByFile(
            @ApiParam(value = "待搜索的图片文件", required = true) @RequestParam("file") MultipartFile file,
            @ApiParam(value = "相似度阈值（0-1），不传则使用配置的默认值") @RequestParam(value = "threshold", required = false) Float threshold,
            @ApiParam(value = "返回前K个匹配结果，默认1") @RequestParam(value = "topK", required = false, defaultValue = "1") Integer topK) {

        // 使用配置的默认阈值
        if (threshold == null) {
            threshold = faceRecognitionProperties.getThreshold();
        }

        FaceSearchRespDTO result = faceRecognitionService.searchFaceByFile(file, threshold, topK);
        if (result != null && result.isSuccess()) {
            return ResponseResult.success(result.getData());
        }
        return ResponseResult.failed(result != null ? result.getMsg() : "人脸搜索失败");
    }

}

